<template>
  <view>
    <!-- 支持 uView List 所有 Props、Events -->
    <!-- 是否滚动触底自动加载数据（默认不使用）使用时必传 requestFn total currentPage -->
    <u-list :showScrollbar="showScrollbar" :lowerThreshold="lowerThreshold" :upperThreshold="upperThreshold"
      :scrollTop="scrollTop" :offsetAccuracy="offsetAccuracy" :enableFlex="enableFlex" :pagingEnabled="pagingEnabled"
      :scrollable="scrollable" :scrollIntoView="scrollIntoView" :scrollWithAnimation="scrollWithAnimation"
      :enableBackToTop="enableBackToTop" :height="height" :width="width" :preLoadScreen="preLoadScreen"
      @scroll="handleScroll" @scrolltolower="handleScrolltolower">
      <u-list-item v-for="(item, index) in listData" :key="index">
        <slot :row="item" />
      </u-list-item>
      <u-list-item key="load">
        <view style="padding-bottom: 30px;">
          <u-loadmore v-if="!isScrolltolowerAutoLoad || (this.size * this.currentPage) >= this.total" status="nomore" />
          <u-loadmore v-else-if="loading" status="loading" />
        </view>
      </u-list-item>
    </u-list>
  </view>
</template>

<script>
  export default {
    name: 'DList',
    props: {
      showScrollbar: {
        type: Boolean,
        default: false
      },
      lowerThreshold: {
        type: [String, Number],
        default: 50
      },
      upperThreshold: {
        type: [String, Number],
        default: 0
      },
      scrollTop: {
        type: [String, Number],
        default: 0
      },
      offsetAccuracy: {
        type: [String, Number],
        default: 10
      },
      enableFlex: {
        type: Boolean,
        default: false
      },
      pagingEnabled: {
        type: Boolean,
        default: false
      },
      scrollable: {
        type: Boolean,
        default: true
      },
      scrollIntoView: {
        type: String,
        default: undefined
      },
      scrollWithAnimation: {
        type: Boolean,
        default: false
      },
      enableBackToTop: {
        type: Boolean,
        default: false
      },
      height: {
        type: [String, Number],
        default: 0
      },
      width: {
        type: [String, Number],
        default: 0
      },
      preLoadScreen: {
        type: [String, Number],
        default: 1
      },
      // 列表数据
      listData: {
        type: Array,
        default () {
          return []
        }
      },
      // 是否滚动触底自动加载数据（默认不使用）
      isScrolltolowerAutoLoad: {
        type: Boolean,
        default: false
      },
      // 使用滚动触底自动加载数据时需要传的函数，函数需要返回一个Promise，Promise状态成功时 会自动加一
      requestFn: {
        type: Function,
        default () {
          return Promise.resolve
        }
      },
      // 接口每次返回条目个数（使用滚动触底自动加载数据时需要传）
      size: {
        type: Number,
        default: 10
      },
      // 总条目数（使用滚动触底自动加载数据时需要传）
      total: {
        type: Number,
        default: 0
      },
      // 当前已加载条目页数（使用滚动触底自动加载数据时需要传，支持 .sync）
      currentPage: {
        type: Number,
        default: 1
      },
    },
    data() {
      return {
        // 是否加载中
        loading: false,
        loadingPage: 0
      };
    },
    methods: {
      handleScroll(scrollTop) {
        this.$emit('scroll', scrollTop)
      },
      handleScrolltolower(e) {
        if (this.isScrolltolowerAutoLoad && (this.size * this.currentPage) < this.total && this.currentPage + 1 !== this
          .loadingPage) {
          this.loading = true
          // 记录当前请求的page，防止发送多次参数一样的请求
          this.loadingPage = this.currentPage + 1
          // 使用 .bind(this.$parent) 的原因是因为 在测试中发现微信小程序的 requestFn 方法的this和h5是不一样的，所以用bind改变了this指向来抹平差异
          const requestFn = this.requestFn.bind(this.$parent)
          uni.$u.throttle(() => {
            requestFn({
              size: this.size,
              page: this.loadingPage
            }).then(() => {
              this.$emit('update:currentPage', this.loadingPage)
            }).finally(() => {
              // 请求结束后同步page
              this.loadingPage = this.currentPage
              this.loading = false
            })
          }, 500)
        }
        this.$emit('scrolltolower')
      }
    },
  };
</script>

<style lang="scss" scoped>
</style>